home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d17 / prform17.arc / PRFORM.C < prev    next >
Text File  |  1988-06-16  |  15KB  |  708 lines

  1. /*
  2.  * PRFORM - PRintout FORMatter by Richard Conn 
  3.  *
  4.  * PRFORM generates a formatted listing of a text file with headers at
  5.  * the top of each page, wraparound if lines exceed the width of a
  6.  * page, etc.  PRFORM sends its output to either standard output (the
  7.  * default) or a text file. 
  8.  *
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <time.h>
  13.  
  14. #define VERSION "PRFORM Version 1.7 (Beta Test)"
  15.  
  16. #define MSDOS /* Uncomment to compile under MSDOS & TURBO-C */
  17.  
  18. #define MAXLL 400
  19. #define DEFSTART 1
  20. #define DEFENDL 0
  21. #define DEFNLINES 62
  22. #define DEFLM 5
  23. #define DEFLL 80
  24. #define DEFTABS 8
  25. #define DEFERASE 0
  26. #define DEFHEAD "frp"
  27. #define DEFEHEAD ""
  28. #define DEFOHEAD ""
  29. #define DEFHTEXT ""
  30. #define DEFPNUM 1
  31.  
  32. #ifndef MSDOS
  33. #define TEMPFILENAME "/tmp/prform"
  34. #endif                /* MSDOS */
  35.  
  36. #define HEADLEN 400
  37. #define FORMFEED '\014'
  38.  
  39. /* Options and their default values */
  40. int             erase = DEFERASE;
  41. int             fileout = 0;    /* 0 if standard out, 1 if file, 2 if
  42.                  * none */
  43. char            head[HEADLEN] = DEFHEAD;
  44. char            ehead[HEADLEN] = DEFEHEAD;
  45. char            ohead[HEADLEN] = DEFOHEAD;
  46. char            htext[HEADLEN] = DEFHTEXT;
  47. int             ll = DEFLL;
  48. int             lm = DEFLM;
  49. int             numberlines = 0;
  50. int             nlines = DEFNLINES;
  51. int             start = DEFSTART;
  52. int             endl = DEFENDL;
  53. int             tabs = DEFTABS;
  54. int             onepass = 0;
  55. int             fpnum = DEFPNUM;
  56.  
  57. int             totalpages = 0;
  58. int             error = 0;
  59. long            linenum;
  60. int             lcount;
  61. int             pagenum;
  62. int             pnum;
  63. int             prok;
  64. char           *curdt;
  65. FILE           *fpo;
  66.  
  67. main(argc, argv)
  68.     int             argc;
  69.     char           *argv[];
  70. {
  71.     int             i;
  72.     long            seconds;
  73.     char           *rover;
  74.     char           *ctime();
  75.     int             lastfile = 0;
  76.     int             printdone = 0;
  77.     int             origfileout;
  78.     int             getpid();
  79.  
  80. #ifndef MSDOS
  81.     char            tempfile[100];
  82.     int             unlink();
  83.     FILE           *fp, *fopen();
  84.     char            inline[MAXLL];
  85. #endif
  86.  
  87.     /* Get current time and set string */
  88.     time(&seconds);
  89.     curdt = ctime(&seconds);
  90.     rover = curdt;
  91.     while (*rover) {
  92.     if (*rover == '\n')
  93.         *rover = '\0';
  94.     else
  95.         rover++;
  96.     }
  97.  
  98. #ifndef MSDOS
  99.     /* Create temporary file name if needed */
  100.     sprintf(tempfile, "%s%d", TEMPFILENAME, getpid());
  101. #endif
  102.  
  103.     /* Process each argument as an option or file to print */
  104.     for (i = 1; i < argc; i++) {
  105.     if (*argv[i] == '-') {
  106.         if (lastfile) {
  107.         lastfile = 0;
  108.         resetopts();
  109.         }
  110.         option(&argv[i][1]);
  111.     } else {
  112.         lastfile = 1;
  113.         if (!onepass) {
  114.         origfileout = fileout;
  115.         fileout = 2;
  116.         print(argv[i], "");
  117.         fileout = origfileout;
  118.         totalpages = pnum - 1;
  119.         } else
  120.         totalpages = 0;
  121.         print(argv[i], "");
  122.         printdone = 1;
  123.     }
  124.     }
  125.  
  126.     /* Print from standard input if no files specified */
  127.     if (!printdone && !error) {
  128.  
  129. #ifndef MSDOS
  130.     if ((fp = fopen(tempfile, "w")) == NULL) {
  131.         fprintf(stderr, " Cannot Create Temporary File %s\n", tempfile);
  132.         exit(1);
  133.     }
  134.     while (gets(inline, MAXLL))
  135.         fprintf(fp, "%s\n", inline);
  136.     fclose(fp);
  137.     totalpages = 0;
  138.     if (!onepass) {
  139.         origfileout = fileout;
  140.         fileout = 2;
  141.         print("", tempfile);
  142.         fileout = origfileout;
  143.         totalpages = pnum - 1;
  144.     } else
  145.         totalpages = 0;
  146.     print("", tempfile);
  147.     unlink(tempfile);
  148. #else
  149.     help();
  150. #endif
  151.  
  152.     }
  153.     /* Close output file if open */
  154.     if (fileout == 1)
  155.     fclose(fpo);
  156.  
  157.     /* Exit program */
  158.     exit(0);
  159. }
  160.  
  161. /* Reset options to default values */
  162. resetopts()
  163. {
  164.     char           *rover1, *rover2;
  165.  
  166.     /* Reset -e default */
  167.     endl = DEFENDL;
  168.  
  169.     /* Reset -E default */
  170.     onepass = 0;
  171.  
  172.     /* Reset -h defaults */
  173.     strcpy(head, DEFHEAD);
  174.     strcpy(ehead, DEFEHEAD);
  175.     strcpy(ohead, DEFOHEAD);
  176.  
  177.     /* Reset -l default */
  178.     ll = DEFLL;
  179.  
  180.     /* Reset -m default */
  181.     lm = DEFLM;
  182.  
  183.     /* Reset -M default */
  184.     strcpy(htext, DEFHTEXT);
  185.  
  186.     /* Reset -n default */
  187.     numberlines = 0;
  188.  
  189.     /* Do not reset -o */
  190.  
  191.     /* Reset -p default */
  192.     nlines = DEFNLINES;
  193.  
  194.     /* Reset -s default */
  195.     start = DEFSTART;
  196.  
  197.     /* Reset -S default */
  198.     fpnum = DEFPNUM;
  199.  
  200.     /* Reset -t default */
  201.     tabs = DEFTABS;
  202.  
  203.     /* Reset -T default */
  204.     erase = 0;
  205.  
  206. }
  207.  
  208. /* Process options */
  209. option(text)
  210.     char           *text;
  211. {
  212.     char           *rover1, *rover2;
  213.     FILE           *fopen();
  214.     int             cont;
  215.  
  216.     cont = 1;
  217.     while (cont && *text) {
  218.     switch (*text) {
  219.     case 'a':
  220.         erase = 0;
  221.         *head = '\0';
  222.         *ehead = '\0';
  223.         *ohead = '\0';
  224.         ll = MAXLL;
  225.         lm = 0;
  226.         numberlines = 0;
  227.         nlines = 0;
  228.         start = DEFSTART;
  229.         tabs = DEFTABS;
  230.         break;
  231.     case 'e':
  232.         endl = atoi(++text);
  233.         cont = 0;
  234.         break;
  235.     case 'E':
  236.         onepass = 1;
  237.         break;
  238.     case 'h':
  239.         rover1 = ++text;
  240.         switch (*rover1) {
  241.         case 'e':
  242.         case 'E':
  243.         rover1++;
  244.         rover2 = ehead;
  245.         break;
  246.         case 'o':
  247.         case 'O':
  248.         rover1++;
  249.         rover2 = ohead;
  250.         break;
  251.         default:
  252.         rover2 = head;
  253.         break;
  254.         }
  255.         strcpy(rover2, rover1);
  256.         cont = 0;
  257.         break;
  258.     case 'H':
  259.         help();
  260.         error = 1;
  261.         cont = 0;
  262.         break;
  263.     case 'l':
  264.         ll = atoi(++text);
  265.         if (ll == 0)
  266.         ll = DEFLL;
  267.         cont = 0;
  268.         break;
  269.     case 'm':
  270.         lm = atoi(++text);
  271.         cont = 0;
  272.         break;
  273.     case 'M':
  274.         strcpy(htext, ++text);
  275.         cont = 0;
  276.         break;
  277.     case 'n':
  278.         numberlines = 1;
  279.         lm = 8;
  280.         break;
  281.     case 'o':
  282.         if (fileout == 1)
  283.         fclose(fpo);
  284.         if ((fpo = fopen(++text, "w")) == NULL) {
  285.         fprintf(stderr, " Cannot Open Output File %s\n", text);
  286.         exit(0);
  287.         }
  288.         fileout = 1;
  289.         cont = 0;
  290.         break;
  291.     case 'p':
  292.         nlines = atoi(++text);
  293.         cont = 0;
  294.         break;
  295.     case 's':
  296.         start = atoi(++text);
  297.         fpnum = start;
  298.         cont = 0;
  299.         break;
  300.     case 'S':
  301.         fpnum = atoi(++text);
  302.         cont = 0;
  303.         break;
  304.     case 't':
  305.         tabs = atoi(++text);
  306.         cont = 0;
  307.         if (tabs == 0)
  308.         tabs = DEFTABS;
  309.         break;
  310.     case 'T':
  311.         erase = 1;
  312.         break;
  313.     default:
  314.         fprintf(stderr, " Invalid Option at %s\n", text);
  315.         help();
  316.         error = 1;
  317.         break;
  318.     } if (cont)
  319.         text++;
  320.     }
  321. }
  322.  
  323. /* Print help message */
  324. help()
  325. {
  326.     fprintf(stderr,
  327.         "%s\n", VERSION);
  328.     fprintf(stderr,
  329.         " Parameters: [[-option ...] [filename ...]] ...\n");
  330.     fprintf(stderr,
  331.         " Options:\n");
  332.     fprintf(stderr,
  333.     "  -a       as-is output (expand tabs and page breaks only)\n");
  334.     fprintf(stderr,
  335.         "  -e#      end printing after the #th page\n");
  336.     fprintf(stderr,
  337.         "  -E       no ending line number in page count\n");
  338.     fprintf(stderr,
  339.         "  -hfMprt  sets the page heading\n");
  340.     fprintf(stderr,
  341.         "     f   places the file name into the page heading\n");
  342.     fprintf(stderr,
  343.         "     M   places the header message (defined by -M)\n");
  344.     fprintf(stderr,
  345.         "          into the page heading\n");
  346.     fprintf(stderr,
  347.      "     p   places the page number into the page heading\n");
  348.     fprintf(stderr,
  349.      "     r   places the rest of the heading on the right side\n");
  350.     fprintf(stderr,
  351.        "     t   places the date and time into the page heading\n");
  352.     fprintf(stderr,
  353.         "         no option after h sets no page heading\n");
  354.     fprintf(stderr,
  355.         "          (default option sequence is %s)\n", DEFHEAD);
  356.     fprintf(stderr,
  357.         "  -hefMprt sets the page heading for even pages\n");
  358.     fprintf(stderr,
  359.         "          (default option sequence is %s)\n", DEFEHEAD);
  360.     fprintf(stderr,
  361.         "  -hofMprt sets the page heading for odd pages\n");
  362.     fprintf(stderr,
  363.         "          (default option sequence is %s)\n", DEFOHEAD);
  364.     fprintf(stderr,
  365.         "  -H       prints this help message on stderr and exits\n", DEFLL);
  366.     fprintf(stderr,
  367.         "  -l#      is the length of a line (def %d)\n", DEFLL);
  368.     fprintf(stderr,
  369.         "  -m#      is the length of the left margin (def %d)\n",
  370.         DEFLM);
  371.     fprintf(stderr,
  372.         "  -M<text> sets the header message to <text>\n");
  373.     fprintf(stderr,
  374.       "  -n       causes each line to be numbered (-M set to 8)\n");
  375.     fprintf(stderr,
  376.         "  -o<name> redirects the output listing to the indicated file\n");
  377.     fprintf(stderr,
  378.     "  -p#      is the number of lines/page (def %d)\n", DEFNLINES);
  379.     fprintf(stderr,
  380.         "  -s#      start printing at the #th page (def %d)\n", DEFSTART);
  381.     fprintf(stderr,
  382.     "          (note: also does -S#, setting first page number)\n");
  383.     fprintf(stderr,
  384.       "  -S#      sets the number of the first printed page\n");
  385.     fprintf(stderr,
  386.       "  -t#      is the number of columns per tab stop (def %d)\n",
  387.         DEFTABS);
  388.     fprintf(stderr,
  389.         "  -T       truncate lines which are too long\n");
  390.  
  391. #ifdef MSDOS
  392.     fprintf(stderr,
  393.      "Using PRFORM as a filter is not supported under MSDOS\n");
  394. #endif
  395.  
  396. }
  397.  
  398. /* Main print function for a file */
  399. print(filename, tempfile)
  400.     char           *filename;
  401.     char           *tempfile;
  402. {
  403.     FILE           *fp, *fopen();
  404.     char            inline[MAXLL];
  405.  
  406.     if (error)
  407.     return;
  408.     pnum = fpnum;
  409.     pagenum = 1;
  410.     linenum = 1;
  411.     if (start <= pagenum)
  412.     prok = 1;
  413.     else
  414.     prok = 0;
  415.     if (*filename) {
  416.     if ((fp = fopen(filename, "r")) == NULL) {
  417.         fprintf(stderr, " Cannot Open %s\n", filename);
  418.         error = 1;
  419.         return;
  420.     }
  421.     } else {
  422.     if ((fp = fopen(tempfile, "r")) == NULL) {
  423.         fprintf(stderr, " Cannot Open Temporary File %s\n", tempfile);
  424.         error = 1;
  425.         return;
  426.     }
  427.     }
  428.     pagehead(filename);
  429.     while (fgets(inline, MAXLL, fp) != NULL) {
  430.     inline[strlen(inline) - 1] = '\0';
  431.     prline(filename, inline, 0);
  432.     }
  433.     pageeject();
  434.     fclose(fp);
  435. }
  436.  
  437. /* Eject Page for next listing */
  438. pageeject()
  439. {
  440.     prc(FORMFEED);
  441.     pagenum++;
  442.     if (start < pagenum)
  443.     pnum++;
  444.     if (start <= pagenum) {
  445.     if (endl && (pagenum > endl))
  446.         prok = 0;
  447.     else
  448.         prok = 1;
  449.     } else
  450.     prok = 0;
  451. }
  452.  
  453. /* Print Page Heading */
  454. pagehead(heading)
  455.     char           *heading;
  456. {
  457.     char           *rover;
  458.     char            rhead[HEADLEN];
  459.     char            lhead[HEADLEN];
  460.     char            outhead[HEADLEN];
  461.     char           *output;
  462.     int             olen;
  463.     int             i;
  464.  
  465.     if (prok) {
  466.     *rhead = '\0';
  467.     *lhead = '\0';
  468.     output = lhead;
  469.  
  470.     /* Output heading if any kind of heading has been defined */
  471.     if (*head || *ehead || *ohead) {
  472.         prsp(0);
  473.         rover = head;
  474.         if ((pnum % 2) && *ohead)
  475.         rover = ohead;
  476.         if ((pnum % 2 == 0) && *ehead)
  477.         rover = ehead;
  478.         while (*rover) {
  479.         switch (*rover) {
  480.         case 'f':
  481.             sprintf(output, "%s    ", heading);
  482.             output = &output[strlen(output)];
  483.             break;
  484.         case 'M':
  485.             sprintf(output, "%s", htext);
  486.             output = &output[strlen(output)];
  487.             break;
  488.         case 'p':
  489.             if (totalpages)
  490.             sprintf(output, "Page %d of %d    ", pnum,
  491.                 totalpages);
  492.             else
  493.             sprintf(output, "Page %d    ", pnum);
  494.             output = &output[strlen(output)];
  495.             break;
  496.         case 'r':
  497.             *output = '\0';
  498.             output = rhead;
  499.             break;
  500.         case 't':
  501.             sprintf(output, "%s    ", curdt);
  502.             output = &output[strlen(output)];
  503.             break;
  504.         default:
  505.             break;
  506.         }
  507.         rover++;
  508.         }
  509.         *output = '\0';
  510.  
  511.         /* Strip trailing spaces off the right and left headings */
  512.         rover = rhead;
  513.         output = rover;
  514.         while (*rover) {
  515.         if (*rover != ' ')
  516.             output = rover;
  517.         rover++;
  518.         }
  519.         if (*output)
  520.         *++output = '\0';
  521.         rover = lhead;
  522.         output = rover;
  523.         while (*rover) {
  524.         if (*rover != ' ')
  525.             output = rover;
  526.         rover++;
  527.         }
  528.         if (*output)
  529.         *++output = '\0';
  530.  
  531.         /*
  532.          * Build the composite heading from the left and right
  533.          * headings 
  534.          */
  535.         olen = (ll - lm) - (strlen(rhead) + strlen(lhead));
  536.         if (olen < 0)
  537.         olen = 0;
  538.         output = outhead;
  539.         rover = lhead;
  540.         while (*rover)
  541.         *output++ = *rover++;
  542.         for (i = 0; i < olen; i++)
  543.         *output++ = ' ';
  544.         rover = rhead;
  545.         while (*rover)
  546.         *output++ = *rover++;
  547.         *output = '\0';
  548.  
  549.         /*
  550.          * Print the composite heading to a file or standard
  551.          * output 
  552.          */
  553.         if (fileout == 1)
  554.         fprintf(fpo, "%s\n\n", outhead);
  555.         else {
  556.         if (fileout == 0)
  557.             printf("%s\n\n", outhead);
  558.         }
  559.         /* Two lines have been output */
  560.         lcount = 2;
  561.     } else
  562.         /* No lines have been output */
  563.         lcount = 0;
  564.     } else {
  565.     if (*head || *ehead || *ohead)
  566.         lcount = 2;
  567.     else
  568.         lcount = 0;
  569.     }
  570. }
  571.  
  572. /* Print Line on page */
  573. prline(heading, line, cont)
  574.     char           *heading;
  575.     char           *line;
  576.     int             cont;
  577. {
  578.     char           *rover1, *rover2;
  579.     int             len;
  580.     int             cchar;
  581.     int             looping;
  582.  
  583.     if (cont && !numberlines)
  584.     len = ll - lm - 3;
  585.     else
  586.     len = ll - lm;
  587.     if (nlines) {
  588.     if (lcount >= nlines) {
  589.         pageeject();
  590.         pagehead(heading);
  591.     }
  592.     }
  593.     if (cont && !numberlines)
  594.     prs(">> ");
  595.     if (cont)
  596.     prsp(0);
  597.     else
  598.     prsp(1);
  599.     rover1 = line;
  600.     cchar = 0;
  601.     looping = 1;
  602.     while (looping) {
  603.     switch (*rover1) {
  604.     case '\t':
  605.         prs(" ");
  606.         cchar++;
  607.         while (cchar % tabs) {
  608.         prs(" ");
  609.         cchar++;
  610.         }
  611.         rover1++;
  612.         if (cchar >= len) {
  613.         rover2 = rover1;
  614.         while (*rover2 == ' ')
  615.             rover2++;
  616.         if (*rover2) {
  617.             prs("\n");
  618.             lcount++;
  619.             if (!erase)
  620.             prline(heading, rover1, 1);
  621.             looping = 0;
  622.         }
  623.         }
  624.         break;
  625.     case FORMFEED:
  626.         prs("\n");
  627.         pageeject();
  628.         pagehead(heading);
  629.         cchar = 0;
  630.         rover1++;
  631.         break;
  632.     case '\0':
  633.         prs("\n");
  634.         lcount++;
  635.         looping = 0;
  636.         break;
  637.     default:
  638.         prc(*rover1++);
  639.         cchar++;
  640.         if (cchar >= len) {
  641.         rover2 = rover1;
  642.         while (*rover2 == ' ')
  643.             rover2++;
  644.         if (*rover2) {
  645.             prs("\n");
  646.             lcount++;
  647.             if (!erase)
  648.             prline(heading, rover1, 1);
  649.             looping = 0;
  650.         }
  651.         }
  652.         break;
  653.     }
  654.     }
  655. }
  656.  
  657. /* Print leading spaces */
  658. prsp(putnumber)
  659.     int             putnumber;
  660. {
  661.     int             i;
  662.  
  663.     if (numberlines) {
  664.     if (putnumber) {
  665.         if (fileout == 1)
  666.         fprintf(fpo, "%7ld ", linenum++);
  667.         else {
  668.         if (fileout == 0)
  669.             printf("%7ld ", linenum++);
  670.         }
  671.     } else {
  672.         prs("        ");
  673.     }
  674.     } else {
  675.     if (lm > 0)
  676.         for (i = 0; i < lm; i++)
  677.         prs(" ");
  678.     }
  679. }
  680.  
  681. /* Print a character based on PROK flag */
  682. prc(ch)
  683.     char            ch;
  684. {
  685.     if (prok) {
  686.     if (fileout == 1)
  687.         fprintf(fpo, "%c", ch);
  688.     else {
  689.         if (fileout == 0)
  690.         printf("%c", ch);
  691.     }
  692.     }
  693. }
  694.  
  695. /* Print a string based on PROK flag */
  696. prs(str)
  697.     char           *str;
  698. {
  699.     if (prok) {
  700.     if (fileout == 1)
  701.         fprintf(fpo, "%s", str);
  702.     else {
  703.         if (fileout == 0)
  704.         printf("%s", str);
  705.     }
  706.     }
  707. }
  708.